?
ko.observableArray.fn.isObservableArray = true;




window.kocrm =
{
    bindOnLoad: function (n, c) {
        var w = document.getElementById(n);
        if (w.addEventListener)
            w.addEventListener("load", c, false);
        else if (w.attachEvent)
            w.attachEvent("onload", c);
    },

    bindChildFrames: function () {
        var me = this;
        Xrm.Page.ui.controls.forEach(function (control, index) {
            if (control.getControlType() == "iframe" || control.getControlType() == "webresource") {
                var childWindow = window.frames[control.getName()];
                if (!childWindow.attached) {
                    childWindow.attached = true;
                    me.bindOnLoad(control.getName(), function () {
                        me.bindFrame(control.getName());
                    });
                }
                me.bindFrame(control.getName());
            }
        });
    },
    bindFrame: function (frameName) {
        var childWindow = window.frames[frameName];
        var me = this;
        if (childWindow.doBinding && !childWindow.bound) {
            childWindow.bound = true;
            childWindow.ko = ko;
            childWindow.doBinding(ko, me.model);
        }
    },
    bindToCrmModel: function () {
        this.initializeCustomBindings();
        this.model = {}
        var me = this;
        Xrm.Page.data.entity.attributes.forEach(function (attribute, index) {
            var computed = me.createObservable(attribute);
            me.model[attribute.getName()] = computed;
        });

        this.bindChildFrames();

        window.model = this.model;
    },

    initializeCustomBindings: function () {
    },

    createObservable: function (attribute) {
        switch (attribute.getAttributeType()) {
            case "lookup":
                return this.createLookupObservable(attribute);
                break;
            default:
                return this.createStandardObservable(attribute);
                break;
        }

    },

    createStandardObservable: function (attribute) {
        var observable = ko.observable(attribute.getValue());
        attribute.addOnChange(function () {
            if (attribute.getValue() != observable())
                observable(attribute.getValue());
        }, false);

        observable.subscribe(function (newValue) {
            attribute.setValue(newValue);
        });

        return observable;
    },

    createLookupObservable: function (attribute) {

        var observable = ko.observableArray(attribute.getValue());
        attribute.addOnChange(function () {
            if (attribute.getValue() != observable())
                observable(attribute.getValue());
        }, false);

        observable.subscribe(function (newValue) {
            attribute.setValue(newValue);
        });

        return observable;
    }
}

ko.observable.fn.integer = function () {
    return ko.computed({
        read: function () {
            return this();
        },
        write: function (value) {
            this(parseInt(value, 10));
            if (isNaN(this()))
                this(0);
        }
    }, this);
}

